﻿using System.Collections.Generic;
using System.Linq;
using CID.Domain.Exceptions;
using NailsFramework.Persistence;

namespace CID.Domain.Infrastructure
{
    public class Parameter : Model<Parameter>, IParameter
    {
        /// <summary>
        /// Enumerates the system reserved names for the additional parameters
        /// </summary>
        /// <remarks>If new names are added to this class, those needs to be included in <see cref="CID.Execution.Support.Information.ParameterValueInfo.ReservedParameterNames"/> </remarks>
        public static class ReservedNames
        {
            public const string ComponentName = "ComponentName";
            public const string VersionName = "VersionName";
            public const string ReleaseName = "ReleaseName";
            public const string PackageComment = "PackageComment";
            public const string PackagePath = "PackagePath";
            public const string TargetServerAddress = "TargetServerAddress";
            public const string TargetServersAddresses = "TargetServersAddresses";

            public static readonly IEnumerable<string> All = new string[] { ComponentName, VersionName, ReleaseName, PackageComment, PackagePath, TargetServerAddress, TargetServersAddresses };

            public static bool IsReserved(string name)
            {
                return All.Contains(name);
            }
        }
        private string name;

        public virtual int Id { get; private set; }
        public virtual string Name 
        {
            get { return name; }
            set 
            {
                if (ReservedNames.IsReserved(value)) throw new InvalidParameterNameException(value);
                name = value;
            }
        }
        public virtual string Description { get; set; }
        public virtual ParameterType Type { get; set; }

        public virtual ITemplate Template { get; private set; }

        protected Parameter()
        {
            Type = ParameterType.String;
        }

        internal Parameter(string name, string description, ParameterType type, ITemplate template) : this()
        {
            Name = name;
            Description = description;
            Type = type;
            Template = template;
        }

        #region Equals and GetHashCode
        //This class needs to have the Equals overriden to support the comparison with the proxies from the persistence layer
        public override bool Equals(object obj)
        {
            return EntityEqualityHelper.Equals(this, obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        #endregion

        public virtual void RemoveFromTemplate()
        {
            Template = null;
        }
    }
}
